package com.thinkgsp.jxc.persistence.mybatis;

import java.util.HashMap;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import com.thinkgsp.sys.model.SysUser;

/**
 * Mapper 参数插件，在按部门查询的语句中加入参数deptId的值
 * @author evan
 *
 */
@Intercepts({@Signature(
		  type= Executor.class,
		  method = "query",
		  args = {MappedStatement.class,Object.class, RowBounds.class,  
              ResultHandler.class})})
public class ParametersPlugin implements Interceptor {

	private Log log = LogFactory.getLog(ParametersPlugin.class);
	@SuppressWarnings("unchecked")
	public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameter = invocation.getArgs()[1];
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        if(parameter == null) {
        	parameter = new HashMap<String, Object>();
        }
        if(boundSql.getSql().contains("DEPT_ID=?")) {
        	log.debug("sql contain '#{deptId}',add param value in parameters");
        	if(parameter instanceof HashMap) {
            	HashMap<String,Object> params = (HashMap<String,Object>)parameter;
            	if(!params.containsKey("deptId")) {
	    	        Integer deptId = getDeptId();
//	    	        if(deptId != null) {
//	    	        	params.put("deptId", deptId);
//	    	        }
	    	        params.put("deptId", deptId == null ? 0 : deptId);
            	}
        	}
        }
        log.debug(boundSql.getSql());
        return invocation.proceed();
	}

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	public void setProperties(Properties properties) {

	}

	private Integer getDeptId() {
		SecurityContext ctx = SecurityContextHolder.getContext();
		Authentication auth = ctx.getAuthentication();
		SysUser currentUser = null;
        if (auth != null) {
            if (auth.getPrincipal() instanceof UserDetails) {
                currentUser = (SysUser) auth.getPrincipal();
            } else if (auth.getDetails() instanceof UserDetails) {
                currentUser = (SysUser) auth.getDetails();
            }        
        }     
        //if(currentUser == null) return null;
        //if(currentUser.getLogonDept() == null) return null;
        if(currentUser == null || currentUser.getLogonDept() == null) {
        	//throw new ServiceException("用户未登陆或未选择登陆部门。");
        	log.error("ParameterPlugin.getDeptId error:用户未登陆或未选择登陆部门。");
        	return null;
        }
        return currentUser.getLogonDept().getDeptId();	
		//return new Integer(1);
	}
}
